﻿using autoclock.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Text;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using TrOCR.Helper;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolBar;
using Microsoft.Win32;
using System.Net.NetworkInformation;
using Microsoft.VisualBasic.ApplicationServices;
using System.IO;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button;
using System.Text.RegularExpressions;
using System.Media;
using System.Threading;

namespace autoclock
{
    public partial class Form1 : Form
    {
        [DllImport("user32")]
        private static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);

        //下面是可用的常量，根据不同的动画效果声明自己需要的
        private const int AW_HOR_POSITIVE = 0x0001;//自左向右显示窗口，该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志
        private const int AW_HOR_NEGATIVE = 0x0002;//自右向左显示窗口，该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志
        private const int AW_VER_POSITIVE = 0x0004;//自顶向下显示窗口，该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志
        private const int AW_VER_NEGATIVE = 0x0008;//自下向上显示窗口，该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志该标志
        private const int AW_CENTER = 0x0010;//若使用了AW_HIDE标志，则使窗口向内重叠；否则向外扩展
        private const int AW_HIDE = 0x10000;//隐藏窗口
        private const int AW_ACTIVE = 0x20000;//激活窗口，在使用了AW_HIDE标志后不要使用这个标志
        private const int AW_SLIDE = 0x40000;//使用滑动类型动画效果，默认为滚动动画类型，当使用AW_CENTER标志时，这个标志就被忽略
        private const int AW_BLEND = 0x80000;//使用淡入淡出效果


        #region 在窗口结构中为指定的窗口设置信息
        /// <summary>
        /// 在窗口结构中为指定的窗口设置信息
        /// </summary>
        /// <param name="hwnd">欲为其取得信息的窗口的句柄</param>
        /// <param name="nIndex">欲取回的信息</param>
        /// <param name="dwNewLong">由nIndex指定的窗口信息的新值</param>
        /// <returns></returns>
        [DllImport("user32", EntryPoint = "SetWindowLong")]
        private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
        #endregion

        #region 从指定窗口的结构中取得信息
        /// <summary>
        /// 从指定窗口的结构中取得信息
        /// </summary>
        /// <param name="hwnd">欲为其获取信息的窗口的句柄</param>
        /// <param name="nIndex">欲取回的信息</param>
        /// <returns></returns>
        [DllImport("user32", EntryPoint = "GetWindowLong")]
        private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
        #endregion

        private const uint WS_EX_LAYERED = 0x80000;
        private const int WS_EX_TRANSPARENT = 0x20;
        private const int GWL_EXSTYLE = (-20);

        PrivateFontCollection pfc = new PrivateFontCollection(); // using System.Drawing.Text;
        int close_time = 10;//自动关闭时间单位s
        int auto_time = 20;//自动每隔多少分钟显示 单位min
        int timer1_close_time = 0;
        int quickkey = 0;//快捷键是否禁用 0是不
        SoundPlayer player = new SoundPlayer();//音乐
        List<String> alarm = new List<string>();
        int alarm_flag = 0;//闹钟标志
        int alarm_sound_flag = 0;//闹钟音乐标志


        System.Threading.Timer threadTimer;//定时器
        //定义委托
        public delegate void SetTextValue(object value);
        //定义委托
        public delegate void SetForm(int value);
        DateTime now;
        /// <summary>
        /// 添加第三方字体
        /// </summary>
        void AddPrivateFont()
        {
            string file = AppDomain.CurrentDomain.BaseDirectory + "clock.ttf";
            if (!File.Exists(file))
            {
                var fontData1 = Properties.Resources.clockfont;
                unsafe  // 属性设置，生成中 允许不安全代码
                {
                    // 将字体添加到PrivateFontCollection
                    fixed (byte* pFontData = fontData1)
                    {
                        pfc.AddMemoryFont((System.IntPtr)pFontData, fontData1.Length);
                    }
                }
            }
            else
            {
                try
                {
                    pfc.AddFontFile(file);
                }
                catch (Exception)
                {
                    var fontData1 = Properties.Resources.clockfont;
                    unsafe  // 属性设置，生成中 允许不安全代码
                    {
                        // 将字体添加到PrivateFontCollection
                        fixed (byte* pFontData = fontData1)
                        {
                            pfc.AddMemoryFont((System.IntPtr)pFontData, fontData1.Length);
                        }
                    }

                }

            }


        }
        public Form1()
        {
            InitializeComponent();

            StartPosition = FormStartPosition.Manual;

            //int xWidth = SystemInformation.PrimaryMonitorSize.Width;//获取显示器屏幕宽度

            //int yHeight = SystemInformation.PrimaryMonitorSize.Height;//获取显示器屏幕高度

            //Location = new Point(0, 20);//两个参数，一个是距离屏幕左边的高度，一个是距离上方的高度
            AddPrivateFont();
            label1.UseCompatibleTextRendering = true;
            // 使用字体文件提供的字体
            //label1.Font = new Font(pfc.Families[0], 60f);

            readconfig();
            this.Visible = true;
            notifyIcon1.Visible = true;
            now = DateTime.Now;
            label1.Text = now.ToString("HH:mm:ss");

            GetWindowLong(this.Handle, GWL_EXSTYLE);
            SetWindowLong(this.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);

            AnimateWindow(this.Handle, 500, AW_HOR_POSITIVE | AW_ACTIVE | AW_SLIDE);

            SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
            //RegisterHotKey(Handle, 100, KeyModifiers.Shift, Keys.S);

            //读取闹钟
            string file = AppDomain.CurrentDomain.BaseDirectory + "alarm.txt";
            if (File.Exists(file))
            {

                StreamReader sr = File.OpenText(file);
                string nextLine;
                while ((nextLine = sr.ReadLine()) != null)
                {
                    //替换换行
                    alarm.Add(Regex.Replace(nextLine, @"[\r\n]", ""));
                }
                sr.Close();
                alarm_flag = 1;
            }

            //播放准备
            string wavfile = AppDomain.CurrentDomain.BaseDirectory + "alarm.wav";
            if (File.Exists(wavfile))
            {
                try
                {
                    player.SoundLocation = wavfile;
                    player.Load();
                    alarm_sound_flag = 1;
                }
                catch (Exception)
                {

                    MessageBox.Show("音乐载入错误");
                }

            }

            //打开定时
            threadTimer = new System.Threading.Timer(new TimerCallback(TimerUp), null, 0, 1000);
            //threadTimer.Change(0, 1000);

        }



        private void TimerUp(object value)
        {
            if (close_time == 0)
            {
                if (this.Visible == false)
                {
                    //u_FormLoad();
                    this.Invoke(new SetForm(SetFormLoad), 1);
                }
                now = DateTime.Now;
                this.Invoke(new SetTextValue(SetTextBoxValue), now.ToString("HH:mm:ss"));
                //label1.Text = now.ToString("HH:mm:ss");
            }
            else
            {
                if (this.Visible == true)
                {
                    now = DateTime.Now;
                    this.Invoke(new SetTextValue(SetTextBoxValue), now.ToString("HH:mm:ss"));
                    if (close_time > timer1_close_time)
                    {
                        timer1_close_time += 1;
                    }
                    else
                    {
                        timer1_close_time = 0;
                        this.Invoke(new SetForm(SetFormLoad), 0);
                        //u_FormClosing();
                    }

                }
                else
                {
                    //now = now.AddSeconds(1);
                    now = DateTime.Now;
                    this.Invoke(new SetTextValue(SetTextBoxValue), now.ToString("HH:mm:ss"));
                }

                //闹钟
                if ((now.Minute % auto_time == 0) && now.Second == 0)
                {
                    timer1_close_time = 0;
                    this.Invoke(new SetForm(SetFormLoad), 1);
                    //u_FormLoad();
                }
                else
                {
                    if (alarm_flag == 1)
                    {
                        var item = alarm.Find((x) => { return x == now.ToString("HHmmss"); });
                        if (item != null)
                        {
                            timer1_close_time = 0;
                            if (alarm_sound_flag == 1)
                            {
                                player.Play();
                            }
                            this.Invoke(new SetForm(SetFormLoad), 1);
                            //u_FormLoad();
                        }
                    }

                }
            }
            
        }

        /// <summary>
        /// 给文本框赋值
        /// </summary>
        /// <param name="value"></param>
        private void SetTextBoxValue(object value)
        {
            label1.Text = value.ToString();
        }
        //开启页面或者关闭
        private void SetFormLoad(int value)
        {
            if (value== 1)
            {
                u_FormLoad();
            }
            else
            {
                u_FormClosing();
            }
            
        }

        //声明常量：(释义可参见windows API)

        const int WS_EX_NOACTIVATE = 0x08000000;

        //重载Form的CreateParams属性，添加不获取焦点属性值。

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= WS_EX_NOACTIVATE;
                return cp;
            }
        }
        private void u_FormClosing()
        {
            if (this.Visible == true)
            {
                AnimateWindow(this.Handle, 500, AW_HOR_NEGATIVE | AW_HIDE | AW_SLIDE);
                this.Visible = false;
            }

        }

        private void u_FormLoad()
        {
            if (!this.Visible)
            {
                timer1_close_time = 0;
                AnimateWindow(this.Handle, 500, AW_HOR_POSITIVE | AW_ACTIVE | AW_SLIDE);
                this.Visible = true;
            }

        }

        //快捷键
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(
                        IntPtr hWnd,                //要定义热键的窗口的句柄
            int id,                     //定义热键ID（不能与其它ID重复）
            KeyModifiers fsModifiers,   //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
            Keys vk                     //定义热键的内容
            );
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(
            IntPtr hWnd,                //要取消热键的窗口的句柄
            int id                      //要取消热键的ID
            );
        //定义了辅助键的名称（将数字转变为字符以便于记忆，也可去除此枚举而直接使用数值）
        [Flags()]
        public enum KeyModifiers
        {
            None = 0,
            Alt = 1,
            Ctrl = 2,
            Shift = 4,
            WindowsKey = 8
        }

        // 
        /// 监视Windows消息
        /// 重载WndProc方法，用于实现热键响应
        /// 
        /// 
        protected override void WndProc(ref Message m)
        {

            const int WM_HOTKEY = 0x0312;
            //按快捷键 
            switch (m.Msg)
            {
                case WM_HOTKEY:
                    switch (m.WParam.ToInt32())
                    {
                        case 100:    //按下的是Shift+S
                            if (this.Visible == true)
                            {
                                u_FormClosing();
                            }
                            else
                            {
                                u_FormLoad();
                            }
                            break;
                    }
                    break;
            }
            base.WndProc(ref m);
        }

        private void 设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (setForm1 f_set = new setForm1())
            {
                if (f_set.ShowDialog() == DialogResult.OK)
                {
                    //Console.WriteLine("123");
                    readconfig();
                    u_FormLoad();
                }
            }
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }


        public void readconfig()
        {


            var value = IniHelper.GetValue("配置", "禁用快捷键");
            if (value == "发生错误")
            {
                quickkey = 0;
            }
            else
            {
                try
                {
                    if (bool.Parse(value) == false)
                    {
                        quickkey = 0;
                    }
                    else
                    {
                        quickkey = 1;
                    }


                }
                catch
                {
                    quickkey = 0;
                }
            }

            if (quickkey == 0)
            {
                value = IniHelper.GetValue("配置", "快捷键");
                if (value == "发生错误")
                {
                    UnregisterHotKey(Handle, 100);
                    RegisterHotKey(Handle, 100, KeyModifiers.Shift, Keys.S);
                }
                else
                {
                    try
                    {

                        string[] arr = value.Split('+');
                        UnregisterHotKey(Handle, 100);
                        var planet = (KeyModifiers)Enum.Parse(typeof(KeyModifiers), arr[0]);
                        int planetNumber = (int)planet;
                        var planet2 = (Keys)Enum.Parse(typeof(Keys), arr[1]);
                        RegisterHotKey(Handle, 100, planet, planet2);
                    }
                    catch
                    {
                        Console.WriteLine("快捷键错误");
                        UnregisterHotKey(Handle, 100);
                        RegisterHotKey(Handle, 100, KeyModifiers.Shift, Keys.S);
                    }
                }
            }
            else
            {
                try
                {
                    UnregisterHotKey(Handle, 100);
                }
                catch (Exception)
                {

                    MessageBox.Show("取消快捷键错误");
                }
            }


            value = IniHelper.GetValue("配置", "提醒间隔");
            if (value == "发生错误")
            {
                auto_time = 20;
            }
            else
            {
                try
                {
                    auto_time = int.Parse(value);
                }
                catch
                {
                    auto_time = 20;
                }
            }

            value = IniHelper.GetValue("配置", "存在时间");
            if (value == "发生错误")
            {
                close_time = 10;
            }
            else
            {
                try
                {
                    close_time = int.Parse(value);
                }
                catch
                {
                    close_time = 10;
                }
            }

            value = IniHelper.GetValue("配置", "透明度");
            if (value == "发生错误")
            {
                this.Opacity = 0.8D;
            }
            else
            {
                try
                {
                    this.Opacity = int.Parse(value) / 100.0D;
                }
                catch
                {
                    this.Opacity = 0.8D;
                }
            }

            value = IniHelper.GetValue("配置", "外框长宽");
            if (value == "发生错误")
            {
                Size = new Size(385, 105);

            }
            else
            {
                try
                {
                    string[] arr2 = value.Split('+');
                    Size = new Size(int.Parse(arr2[0]), int.Parse(arr2[1]));

                }
                catch
                {
                    Size = new Size(385, 105);
                }
            }

            value = IniHelper.GetValue("配置", "时钟文字大小");
            if (value == "发生错误")
            {
                label1.Font = new Font(pfc.Families[0], 60f);
            }
            else
            {
                try
                {
                    label1.Font = new Font(pfc.Families[0], float.Parse(value));
                }
                catch
                {
                    label1.Font = new Font(pfc.Families[0], 60f);
                }
            }

            value = IniHelper.GetValue("配置", "位置");
            if (value == "发生错误")
            {

                Location = new Point(0, 20);
            }
            else
            {
                try
                {
                    string[] arr3 = value.Split('+');
                    Location = new Point(int.Parse(arr3[0]), int.Parse(arr3[1]));
                }
                catch
                {
                    Location = new Point(0, 20);
                }
            }
            Color ucolor = Color.FromArgb(255, 255, 255);
            value = IniHelper.GetValue("配置", "文字颜色");
            if (value == "发生错误")
            {
                label1.ForeColor = ucolor;
            }
            else
            {
                try
                {
                    ucolor = Color.FromArgb(int.Parse(value));
                    label1.ForeColor = ucolor;
                }
                catch
                {
                    label1.ForeColor = ucolor;
                }
            }

            ucolor = Color.FromArgb(0, 0, 0);
            value = IniHelper.GetValue("配置", "背景颜色");
            if (value == "发生错误")
            {
                BackColor = ucolor;
            }
            else
            {
                try
                {
                    ucolor = Color.FromArgb(int.Parse(value));
                    BackColor = ucolor;
                }
                catch
                {
                    BackColor = ucolor;
                }
            }

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        //唤醒

        void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
        {
            switch (e.Mode)
            {
                case PowerModes.Resume://系统挂起到重新唤醒
                    Console.WriteLine("===>" + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "  Resume\n");
                    now = DateTime.Now;
                    break;
                case PowerModes.Suspend://系统挂起到重新唤醒
                    Console.WriteLine("===>" + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "  Suspend\n");
                    now = DateTime.Now;
                    break;
                case PowerModes.StatusChange://系统挂起到重新唤醒
                    Console.WriteLine("===>" + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "  StatusChange\n");
                    now = DateTime.Now;
                    break;
            }
        }
    }
}
